Claude Code 问题排查技能

upT6op

问题背景

在日常开发中,调试占据了大量时间。面对 bug,常见的做法是凭直觉猜测原因,快速尝试修复,不行就换一个方向再试。这种「试错法」看似高效,实际上经常导致:

  • 修复了表面症状,根因仍在,问题反复出现
  • 一次改多处,引入新 bug,问题越改越多
  • 连续尝试多次修复失败,浪费大量时间
flowchart LR
    A[发现 Bug] --> B{凭直觉猜测}
    B --> C[尝试修复 1]
    C --> D{解决了?}
    D -- 没有 --> E[尝试修复 2]
    E --> F{解决了?}
    F -- 没有 --> G[尝试修复 3...]
    G --> H[耗时数小时<br/>可能引入新问题]
    D --  --> I[可能只修了表象]
随机修复的代价

根据实际调试数据对比:系统化排查平均 15-30 分钟解决问题,而随机尝试平均需要 2-3 小时。首次修复成功率分别为 95% 和 40%。

解决方案:Systematic Debugging 技能

Systematic Debugging(系统化调试)是 Superpowers 技能库中的核心技能之一,它将软件工程中的根因分析方法论转化为 Claude Code 的强制工作流程。

核心原则:先找根因,再做修复。没有完成调查,不允许提出修复方案。

安装

npx skills add https://github.com/obra/superpowers --skill systematic-debugging
自动触发

安装后,当 Claude Code 遇到任何 bug、测试失败或异常行为时,会自动进入系统化调试流程,无需手动调用。

适用场景

该技能适用于所有技术问题,不仅限于代码 bug:

场景示例
测试失败单元测试突然不过、集成测试超时
生产 Bug接口返回异常数据、页面白屏
构建失败编译错误、依赖冲突、打包失败
性能问题接口响应慢、内存泄漏
集成异常微服务间调用失败、配置不生效
行为异常功能表现与预期不一致
越紧急越要用

时间压力大时特别容易跳过调查直接改代码。但系统化排查反而更快——因为它避免了反复试错的时间浪费。

四阶段排查流程

Systematic Debugging 将调试过程分为四个强制阶段,必须按顺序完成,不能跳过。

flowchart LR
    A[阶段 1<br/>根因调查] --> B[阶段 2<br/>模式分析]
    B --> C[阶段 3<br/>假设验证]
    C --> D[阶段 4<br/>实施修复]
    D -- 修复失败<br/>不超过3次 --> A
    D -- 3次修复失败 --> E[停下来<br/>质疑架构]

阶段 1:根因调查

这是最关键的阶段。在完成根因调查之前,不允许提出任何修复方案。

1
仔细阅读错误信息

不要跳过错误或警告信息,它们通常包含了解决方案的关键线索。完整阅读堆栈跟踪,记录行号、文件路径和错误码。

2
稳定复现问题

确认能否可靠地触发问题。明确具体的复现步骤,确认是否每次都会出现。如果无法复现,继续收集更多数据,不要猜测。

3
检查最近变更

通过 git diff 或最近的提交记录,排查可能导致问题的变更——包括代码修改、新增依赖、配置变更和环境差异。

4
多组件系统的诊断

当系统涉及多个组件时(如 API → Service → Database),在每个组件边界添加诊断日志,确认数据在哪一层出了问题。

5
追踪数据流

从错误发生的位置沿调用链向上追溯:错误值从哪里来?谁传入了这个错误值?一直追到源头,在源头修复而非在症状处打补丁。

阶段 2:模式分析

找到已有的正确实现,通过对比发现差异。

步骤说明
查找正常案例在同一代码库中找到类似的、能正常工作的代码
完整对比参考实现如果在实现某个模式,完整阅读参考实现的每一行,不要跳读
列出所有差异逐一列出正常代码与异常代码之间的差异,不要假设"这个无关紧要"
理解依赖关系弄清楚当前代码依赖了哪些组件、配置和环境条件

阶段 3:假设与验证

采用科学方法,逐一验证假设。

1
提出单一假设

明确陈述:"我认为根因是 X,因为 Y"。假设必须具体,不能模糊。

2
最小化测试

做最小的改动来验证假设。一次只改一个变量,不要同时修改多处。

3
验证后再继续

验证通过则进入阶段 4;验证不通过则回到阶段 1,用新的信息重新分析,不要在已有修改基础上叠加更多修改。

阶段 4:实施修复

确认根因后,针对性地修复。

1
创建失败测试用例

在修复之前,先写一个能复现问题的测试用例。这个测试当前应该是失败的。

2
实施单一修复

只修复已确认的根因,一次一个改动。不要顺手做"改进"或重构。

3
验证修复结果

确认失败的测试现在通过了,并且没有破坏其他测试。